package cn.geoportal.gmo.mail.service;

import cn.geoportal.gmo.mail.entity.ConvertTaskSend;
import cn.geoportal.gmo.mail.mapper.HandMsgMapper;
import cn.geoportal.gmo.mail.utils.JsonUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @ProjectName: gmo
 * @Package: cn.geoportal.gmo.mail.service
 * @ClassName: HandleMsgService
 * @Author: chiangbt@geoportal.cn
 * @Description: 消息接收服务
 * @Date: 2021/6/6 12:35
 */
@Component
public class HandleMsgService {

    private static Logger log = LoggerFactory.getLogger(HandleMsgService.class);

    @Autowired
    private HandMsgMapper handMsgMapper;

    @Autowired
    private JavaMailSender emailSender;
    @Value("${spring.mail.username}")
    private String emailFrom;

    @Value("${toolpath.osgbtool}")
    private String osgbtool;

    @Value("${toolpath.osgbjson}")
    private String osgbjson;

    @Value("${toolpath.modeltool}")
    private String modeltool;

    @Value("${toolpath.modeljson}")
    private String modeljson;

    @RabbitListener(queues = "test1.queue")
    public void handle1(Channel channel,Map<String,Object> msg, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) throws IOException {
        channel.basicAck(deliveryTag,true);//确认已收到消息

        int taskId = (int)msg.get("taskId");
        String shpCmd = (String)msg.get("shpCmd");
        String type = (String)msg.get("type");
        log.info("Shapefile加载：{}", msg.get("shpCmd"));
        this.executeCmd(taskId,type,shpCmd);
    }

    @RabbitListener(queues = "mail.queue")
    public void handle2(Channel channel, ConvertTaskSend convertTaskSend,@Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) throws Exception {
        channel.basicAck(deliveryTag,true);//确认已收到消息
        int taskId = convertTaskSend.getTaskId();
        String type = convertTaskSend.getType();
        String source = convertTaskSend.getSource();
        String target = convertTaskSend.getTarget();
        String epsg = convertTaskSend.getEpsg();
        String center = convertTaskSend.getCenter();

        log.info(type);

        switch (type){
            case "OSGB":
                String jsonfile = this.createOsgbJson(osgbjson, source, target, epsg, center);
                log.info(jsonfile);
                String cmd = osgbtool + " --task=" + jsonfile;
                log.info(cmd);
                this.executeCmd(taskId,type,cmd);
                break;
            case "CLM":
                String modeljsonfile = this.createModelJson(modeljson, source, target, epsg, center);
                log.info(modeljsonfile);
                String cmd2 = modeltool + " --task=" + modeljsonfile;
                log.info(cmd2);
                this.executeCmd(taskId,type,cmd2);
                break;
            default:
                log.info(convertTaskSend.getSource());
                break;
        }
    }

    public String createOsgbJson(String template, String source, String target, String epsg, String center){
        Map<String, Object> agencyMap = new HashMap<>();
        agencyMap.put("source", source);
        agencyMap.put("target", target);
        agencyMap.put("epsg", epsg);
        agencyMap.put("center", center);

        //模板文件路径
        String jsonString1 = readOsbgTempleAndEdit(agencyMap, template);
        String sourceParent = source.substring(0, source.lastIndexOf("\\"));
        JsonUtil.createJsonFile(jsonString1, sourceParent + "\\", "osgb");
        return sourceParent + "\\osgb.json";
    }

    public String createModelJson(String template, String source, String target, String epsg, String center){
        Map<String, Object> agencyMap = new HashMap<>();
        agencyMap.put("source", source);
        agencyMap.put("target", target);
        agencyMap.put("epsg", epsg);
        agencyMap.put("center", center);
        agencyMap.put("db", source + ".model.db");

        //模板文件路径
        String jsonString1 = readModelTemplateAndEdit(agencyMap, template);
        String sourceParent = source.substring(0, source.lastIndexOf("\\"));
        JsonUtil.createJsonFile(jsonString1, sourceParent + "\\", "model");
        return sourceParent + "\\model.json";
    }

    /**
     * 读取json模板并修改
     * @param agencyMap
     * @param templetePath
     * @return
     */
    public String readOsbgTempleAndEdit(Map<String, Object> agencyMap,String templetePath){
        //读取json模板
        String s = JsonUtil.readJsonFile(templetePath);
        JSONObject jsonObj = JSONObject.parseObject(s);
        //修改模板内容
        JSONObject input = jsonObj.getJSONObject("input");
        input.put("path",agencyMap.get("source"));
        input.put("in_srs",agencyMap.get("epsg"));
        input.put("srsorigin",agencyMap.get("center"));
        jsonObj.put("input",input);
        JSONObject output = jsonObj.getJSONObject("output");

        String source = (String) agencyMap.get("source");
        //输出目录添加源文件同名文件夹
        String substring = source.substring(source.lastIndexOf("\\")+1, source.length());
//        output.put("path",agencyMap.get("target"));
        output.put("path",agencyMap.get("target")+"\\"+substring);
        jsonObj.put("output",output);
        String jsonStr = jsonObj.toJSONString();
        return jsonStr;
    }

    public String readModelTemplateAndEdit(Map<String, Object> agencyMap,String templetePath){
        //读取json模板
        String s = JsonUtil.readJsonFile(templetePath);
        JSONObject jsonObj = JSONObject.parseObject(s);
        //修改模板内容
        JSONArray inputs = jsonObj.getJSONArray("inputs");
        JSONObject input = (JSONObject) inputs.get(0);
        String[] files = new String[1];
        files[0] = (String) agencyMap.get("source");
        input.put("files",files);
        input.put("srs",agencyMap.get("epsg"));
        input.put("srsorigin",agencyMap.get("center"));
        //移除旧数据并添加修改后数据
        inputs.remove(0);
        inputs.add(input);
        jsonObj.put("inputs",inputs);

        JSONObject database = jsonObj.getJSONObject("database");
        JSONObject sqlite = database.getJSONObject("sqlite");
        sqlite.put("file",agencyMap.get("db"));

        JSONObject output = jsonObj.getJSONObject("output");
        //输出目录添加源文件同名文件夹
        String substring = files[0].substring(files[0].lastIndexOf("\\")+1,files[0].lastIndexOf("."));
//        output.put("path",agencyMap.get("target"));
        output.put("path",agencyMap.get("target")+"\\"+substring);
        jsonObj.put("output",output);
        String jsonStr = jsonObj.toJSONString();
        return jsonStr;
    }

    public String executeCmd(int tsskId,String type,String command) {
        try {
            log.info("Execute command : cmd /c " + command);
            //z转换中
            updateStatus(tsskId,type,"1");
            Runtime runtime = Runtime.getRuntime();
            Process process = runtime.exec("cmd /c " + command);
            BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
            String line = null;
            StringBuilder build = new StringBuilder();
            while ((line = br.readLine()) != null) {
                log.info(line);
                build.append(line);
            }
            int i = process.waitFor();
            if(i==0){
                //执行成功
                updateStatus(tsskId,type,"2");
            }else{
                //执行失败
                updateStatus(tsskId,type,"3");
            }
            return build.toString();
        }catch (Exception e) {
            e.printStackTrace();
            //执行失败
            updateStatus(tsskId,type,"3");
            log.info(e.getMessage());
            return "";
        }
    }

    public void updateStatus(int taskId,String type,String status){
        if("shp".equals(type)){
            handMsgMapper.updateShpTaskStatus(taskId,status);
        }else{
            handMsgMapper.updateConvertTaskStatus(taskId,status);
        }
    }

    public static String getDefaultEncoding() {
        if (getOS().trim().toLowerCase().startsWith("win")) {
            return "GBK";
        } else {
            return "UTF-8";
        }
    }

    public static String getOS() {
        String os = System.getProperty("os.name");
        System.out.println(os);
        return os;
    }
}
